package com.baogu.factoryjob.job.handler;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baogu.factoryjob.service.BaoGuDataService;
import com.baogu.factoryjob.service.SensorWarningService;
import com.baogu.factoryjob.service.TerminalWarningService;
import com.baogu.factoryjob.service.remote.SensorWarningRemoteService;
import com.baogu.factoryjob.util.DateUtils;
import com.baogu.factoryjob.util.FastJsonUtils;
import com.baogu.factoryjob.util.UuidUtil;
import com.baogu.model.common.HttpResult;
import com.baogu.model.database.SensorData;
import com.baogu.model.database.SensorWarning;
import com.baogu.model.database.SensorWarningImport;
import com.baogu.model.database.where.SensorDataWhere;
import com.baogu.model.database.where.SensorWarningWhere;
import com.baogu.model.job.*;
import com.baogu.model.job.where.ControllersensorWhere;
import com.baogu.model.job.where.ErrorJobWhere;
import com.baogu.model.job.where.TerminalCollectionWhere;
import com.baogu.model.job.where.TerminalWarningWhere;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.misc.BASE64Encoder;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

@Service @DisallowConcurrentExecution
public class SensorWarningJobHand implements Job {

    private final static int type = 2;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        //获取最新告警信息
        HttpResult httpResult = sensorWarningRemoteService.getNewSensorWarning();
        if(httpResult == null || StringUtils.isEmpty(httpResult.getCode())){
            return;
        }
        JSONArray jsonObject = (JSONArray) httpResult.getData();
        List<JSONObject> impList = jsonObject.toJavaObject(List.class);
        if(impList == null){
            return;
        }
        if(impList.size()==0){
            return;
        }
        List<SensorWarning> allList = new ArrayList<>();
        for(JSONObject jsonObj:impList){
            SensorWarningImport imp = jsonObj.toJavaObject(SensorWarningImport.class);
            String vsion = imp.getVersion();
            if (StringUtils.isEmpty(vsion)){
                //版本号为空
                continue;
            }
            if(imp.getLocalDatetime() == null){
                continue;
            }
            String date =  DateUtils.format(imp.getLocalDatetime(),DateUtils.YYYYMM).substring(0,4);
            // 根据版本号和时间获取告警信息
            httpResult = sensorWarningRemoteService.getSensorSensorWarningByVsion(vsion,date);
            if(httpResult == null || StringUtils.isEmpty(httpResult.getCode())){
                return;
            }
            JSONArray resultOjb = (JSONArray) httpResult.getData();
            List<JSONObject> list = resultOjb.toJavaObject(List.class);
            //保存告警信息
            saveSensorWarning(list,allList,date);
            sensorWarningRemoteService.completeImpSensorWarning(vsion);
        }
        for (SensorWarning sw:allList){
            String collectionPointId = baoGuDataService.isEffective(sw.getControllerId());
            if(StringUtils.isEmpty(collectionPointId)){
                //无效控制器
                saveErrorJob(FastJsonUtils.convertObjectToJSON(sw),"无效控制器",sw.getVersion());
                continue;
            }
            if(sw.getWarningType() == 0){
                Controllersensor controllersensor = new Controllersensor();
                controllersensor.setControllerId(sw.getControllerId());
                updateLastTerminalWarningData(sw,controllersensor,collectionPointId);
                setControllerStatus(sw);
                continue;
            }
            ControllersensorWhere where = new ControllersensorWhere();
            where.setPort(sw.getChannelId());
            where.setControllerId(sw.getControllerId());
            where.setAddrId(sw.getAddrId());
            Controllersensor controllersensor = baoGuDataService.getControllersensorByIdAndPort(where);
            if(controllersensor == null){
                //无关联信息
                saveErrorJob(FastJsonUtils.convertObjectToJSON(sw),"无关联信息",sw.getVersion());
                continue;
            }
            updateLastTerminalWarningData(sw,controllersensor,collectionPointId);
            setControllerStatus(sw);
        }
    }

    @Transactional
    public void reUploadData(ReUploadData reUploadData) throws ParseException {
        System.out.println("重新抽取告警数据开始");
        TerminalWarningWhere terminalCollection = new TerminalWarningWhere();
        terminalCollection.setAddrId(reUploadData.getOldAddrId());
        terminalCollection.setChannelId(reUploadData.getOldPort());
        terminalCollection.setControllerId(reUploadData.getControllerId());
        terminalCollection.setBeginTime(DateUtils.format(reUploadData.getBeginTime(),DateUtils.DATE_TIME_PATTERN));
        terminalCollection.setEndTime(DateUtils.format(reUploadData.getEndTime(),DateUtils.DATE_TIME_PATTERN));
        System.out.println("warnData==>" + DateUtils.format(reUploadData.getBeginTime(),DateUtils.DATE_TIME_PATTERN) + " || " + DateUtils.format(reUploadData.getEndTime(),DateUtils.DATE_TIME_PATTERN));
        terminalWarningService.del(terminalCollection);
        terminalWarningService.delLast(terminalCollection);
        List<SensorWarning> allList = new ArrayList<>();
        List<String> dateList = DateUtils.getYearBetween(reUploadData.getBeginTime(),reUploadData.getEndTime());
        for (String s:dateList){
            SensorWarningWhere where = new SensorWarningWhere();
            where.setBeginTime(reUploadData.getBeginTime());
            where.setEndTime(reUploadData.getEndTime());
            where.setChannelId(reUploadData.getOldPort());
            where.setControllerId(reUploadData.getControllerId());
            where.setAddrId(reUploadData.getOldAddrId());
            where.setTableDate(s);
            List<SensorWarning> list = sensorWarningService.getSensorDataList(where);
            if(list != null && list.size() > 0){
                allList.addAll(list);
            }
        }
        for (SensorWarning sd:allList){
            //sd.setControllerId(reUploadData.getControllerId());
            if(!StringUtils.isEmpty(reUploadData.getNewAddrId())){
                sd.setAddrId(reUploadData.getNewAddrId());
            }
            if(!StringUtils.isEmpty(reUploadData.getNewPort())){
                sd.setChannelId(reUploadData.getNewPort());
            }
        }
        executeReload(allList);
        System.out.println("重新抽取告警数据结束");
    }

    public void executeReload(List<SensorWarning> sensorDataList){
        for (SensorWarning sw:sensorDataList){
            String collectionPointId = baoGuDataService.isEffective(sw.getControllerId());
            if(StringUtils.isEmpty(collectionPointId)){
                //无效控制器
                saveErrorJob(FastJsonUtils.convertObjectToJSON(sw),"无效控制器",sw.getVersion());
                continue;
            }
            if(sw.getWarningType() == 0){
                Controllersensor controllersensor = new Controllersensor();
                controllersensor.setControllerId(sw.getControllerId());
                updateLastTerminalWarningData(sw,controllersensor,collectionPointId);
                setControllerStatus(sw);
                continue;
            }
            ControllersensorWhere where = new ControllersensorWhere();
            where.setPort(sw.getChannelId());
            where.setControllerId(sw.getControllerId());
            where.setAddrId(sw.getAddrId());
            Controllersensor controllersensor = baoGuDataService.getControllersensorByIdAndPort(where);
            if(controllersensor == null){
                //无关联信息
                saveErrorJob(FastJsonUtils.convertObjectToJSON(sw),"无关联信息",sw.getVersion());
                continue;
            }
            updateLastTerminalWarningData(sw,controllersensor,collectionPointId);
            setControllerStatus(sw);
        }
    }

    public void execute(List<ErrorJob> list){
        for (ErrorJob errorJob:list){
            SensorWarning sw = (SensorWarning) FastJsonUtils.convertJsonToObject(errorJob.getData(),SensorWarning.class);
            try {
                if(sw == null){
                    continue;
                }
                String collectionPointId = baoGuDataService.isEffective(sw.getControllerId());
                if(StringUtils.isEmpty(collectionPointId)){
                    //无效控制器
                    System.out.println("无效控制器");
                    continue;
                }
                if(sw.getWarningType() == 0){
                    Controllersensor controllersensor = new Controllersensor();
                    controllersensor.setControllerId(sw.getControllerId());
                    updateLastTerminalWarningData(sw,controllersensor,collectionPointId);
                    setControllerStatus(sw);
                    ErrorJobWhere errorJobWhere = new ErrorJobWhere();
                    errorJobWhere.setId(errorJob.getId());
                    errorJobWhere.setState(1);
                    baoGuDataService.updateErrorJobState(errorJobWhere);
                    continue;
                }
                ControllersensorWhere where = new ControllersensorWhere();
                where.setPort(sw.getChannelId());
                where.setControllerId(sw.getControllerId());
                where.setAddrId(sw.getAddrId());
                Controllersensor controllersensor = baoGuDataService.getControllersensorByIdAndPort(where);
                if(controllersensor == null){
                    //无关联信息
                    System.out.println("无关联信息");
                    continue;
                }
                updateLastTerminalWarningData(sw,controllersensor,collectionPointId);
                setControllerStatus(sw);
                ErrorJobWhere errorJobWhere = new ErrorJobWhere();
                errorJobWhere.setId(errorJob.getId());
                errorJobWhere.setState(1);
                baoGuDataService.updateErrorJobState(errorJobWhere);
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }

    /**
     * 更新控制器状态
     * @param sw
     */
    private void setControllerStatus(SensorWarning sw){
        ControllerStatus controllerStatus = new ControllerStatus();
        controllerStatus.setCollectionPointStatus("0");
        controllerStatus.setControllerId(sw.getControllerId());
        baoGuDataService.setControllerStatus(controllerStatus);
    }

    private Integer updateLastTerminalWarningData(SensorWarning sd,Controllersensor controllersensor,String collectionPointId){
        Integer result = 0;
        if(sd.getWarningType() == 1){
            TerminalWarningWhere where = new TerminalWarningWhere();
            where.setWarningType(1);
            where.setChannelId(controllersensor.getPort());
            where.setControllerId(controllersensor.getControllerId());
            where.setAddrId(controllersensor.getAddrId());
            List<TerminalWarning> list = terminalWarningService.getNewTerminalWarningData(where);
            try{

                for (TerminalWarning tw:list){
                    if (DateUtils.strToDate(tw.getLocalDateTime(),DateUtils.yyyyMMddHHmmssSSS).getTime()>sd.getLocalDateTime().getTime()){
                        continue;
                    }
                    else{
                        terminalWarningService.deleteLastDate(tw.getIdentityId());
                    }
                }
                saveTerminalWarning(sd);
                saveLastTerminalWarning(sd);
                result = 1;
            }catch (Exception ex){
                result = 0;
                saveErrorJob(FastJsonUtils.convertObjectToJSON(sd),ex.getMessage(),sd.getVersion());
            }
            return result;
        }
        else{
            try {
                TerminalWarningWhere where = new TerminalWarningWhere();
                where.setControllerId(controllersensor.getControllerId());
                where.setWarningType(0);
                List<TerminalWarning> list = terminalWarningService.getNewTerminalWarningData(where);
                if(list == null || list.size() == 0){
                    saveTerminalWarning(sd);
                    saveLastTerminalWarning(sd);
                    return result;
                }
                TerminalWarning tw = list.get(0);
                if (DateUtils.strToDate(tw.getLocalDateTime(),DateUtils.yyyyMMddHHmmssSSS).getTime()>sd.getLocalDateTime().getTime()){
                    return result;
                }
                else{
                    terminalWarningService.deleteLastDate(tw.getIdentityId());
                }
                saveTerminalWarning(sd);
                saveLastTerminalWarning(sd);
                return result;
            }catch (Exception ex){
                ex.printStackTrace();
                saveErrorJob(FastJsonUtils.convertObjectToJSON(sd),ex.getMessage(),sd.getVersion());
            }
            return result;
        }

    }
    private Integer saveLastTerminalWarning(SensorWarning sd){
        TerminalWarning terminalWarning = new TerminalWarning();
        BeanUtils.copyProperties(sd,terminalWarning);
        terminalWarning.setIdentityId(UuidUtil.get32UUID());
        terminalWarning.setLocalDateTime(DateUtils.format(sd.getLocalDateTime(),DateUtils.DATE_TIME_PATTERN));
        terminalWarning.setUploadDateTime(DateUtils.format(sd.getUploadDateTime(),DateUtils.DATE_TIME_PATTERN));
        Integer result = 0;
        try{
            result = terminalWarningService.saveLastTerminalWarning(terminalWarning);
        }catch (Exception ex){
            //保存异常
            saveErrorJob(FastJsonUtils.convertObjectToJSON(sd),ex.getMessage(),sd.getVersion());
        }
        return result;
    }

    private Integer saveTerminalWarning(SensorWarning sd){
        TerminalWarning terminalWarning = new TerminalWarning();
        BeanUtils.copyProperties(sd,terminalWarning);
        terminalWarning.setLocalDateTime(DateUtils.format(sd.getLocalDateTime(),DateUtils.DATE_TIME_PATTERN));
        terminalWarning.setUploadDateTime(DateUtils.format(sd.getUploadDateTime(),DateUtils.DATE_TIME_PATTERN));
        terminalWarning.setIdentityId(UuidUtil.get32UUID());
        Integer result = 0;
        try{
            result = terminalWarningService.saveTerminalWarning(terminalWarning);
        }catch (Exception ex){
            saveErrorJob(FastJsonUtils.convertObjectToJSON(sd),ex.getMessage(),sd.getVersion());
            ex.printStackTrace();
        }
        return result;
    }

    private SaveResultData saveSensorWarning(List<JSONObject> list,List<SensorWarning> allList,String tableDate){
        SaveResultData saveResultData = new SaveResultData();
        for (JSONObject jsonObject:list){
            SensorWarningWhere warning = jsonObject.toJavaObject(SensorWarningWhere.class);
            warning.setTableDate(tableDate);
            try{
                Integer result = sensorWarningService.saveData(warning);
                if(result > 0){
                    saveResultData.sussceCount++;
                    allList.add(warning);
                }
                else{
                    saveResultData.failCount++;
                }
            }catch (Exception ex){
                ex.printStackTrace();
                saveErrorJob(FastJsonUtils.convertObjectToJSON(warning),ex.getMessage(),warning.getVersion());
                continue;
            }

        }
        return saveResultData;
    }

    private void saveErrorJob(String data,String msg,String version){
        ErrorJobWhere where = new ErrorJobWhere();
        where.setCreateDate(DateUtils.now());
        where.setUpdateDate(DateUtils.now());
        where.setMsg(msg);
        where.setType(type);
        where.setState(0);
        where.setVersion(version);
        where.setData(data);
        baoGuDataService.saveErrorJob(where);
    }

    @Autowired
    TerminalWarningService  terminalWarningService;
    @Autowired
    SensorWarningService sensorWarningService;
    @Autowired
    SensorWarningRemoteService sensorWarningRemoteService;
    @Autowired
    BaoGuDataService baoGuDataService;

    private class SaveResultData{
        public Integer sussceCount = 0;
        public Integer failCount = 0;
    }
}
